package com.mall.service.impl;

import com.mall.common.BusinessException;
import com.mall.vo.OrderVO;
import java.util.List;
import com.mall.vo.CartVO;
import com.mall.common.PageResult;
import com.mall.dto.OrderCreateDTO;
import com.mall.entity.Order;
import com.mall.entity.OrderItem;
import com.mall.entity.Product;
import com.mall.mapper.OrderItemMapper;
import com.mall.mapper.OrderMapper;
import com.mall.mapper.ProductMapper;
import com.mall.service.CartService;
import com.mall.service.OrderService;
import com.mall.service.ProductService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.stream.Collectors;
import java.time.LocalDateTime;
import java.math.BigDecimal;
import java.util.*;

@Service
public class OrderServiceImpl implements OrderService {

    @Override
    public List<OrderVO.OrderListVO> listOrders(Integer pageNum, Integer pageSize, Integer status) {
        int offset = (pageNum - 1) * pageSize;
        List<Order> orders = orderMapper.selectPage(offset, pageSize, null, status, null);
        if (orders == null || orders.isEmpty()) {
            return Collections.emptyList();
        }
        return orders.stream().map(this::convertToListVO).collect(Collectors.toList());
    }

    @Override
    public void updateOrderByAdmin(Order order) {
        // 只允许修改收货信息和备注
        Order update = new Order();
        update.setId(order.getId());
        update.setReceiverName(order.getReceiverName());
        update.setReceiverPhone(order.getReceiverPhone());
        update.setReceiverAddress(order.getReceiverAddress());
        // update.setRemark(order.getRemark()); // 若无remark字段则注释掉
        orderMapper.updateById(update);
    }

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private ProductService productService;

    @Autowired
    private CartService cartService;
    
    @Override
    @Transactional
    public String createOrder(Long userId, OrderCreateDTO orderCreateDTO) {
        if (orderCreateDTO.getCartIds() == null || orderCreateDTO.getCartIds().isEmpty()) {
            throw new BusinessException("购物车商品不能为空");
        }
        if (!cartService.validateCartItems(userId, orderCreateDTO.getCartIds().toArray(new Long[0]))) {
            throw new BusinessException("购物车商品已失效");
        }
        CartVO.CartSummaryVO cartSummary = cartService.getCheckedCartItems(userId); //获取该用户购买的所有物品
        if (cartSummary == null || cartSummary.getCartItems() == null || cartSummary.getCartItems().isEmpty()) {
            throw new BusinessException("请选择要购买的商品");
        }
        Order order = new Order();
        order.setReceiverName(orderCreateDTO.getReceiverName());
        order.setReceiverAddress(orderCreateDTO.getReceiverAddress());
        order.setReceiverPhone(orderCreateDTO.getReceiverPhone());
        String orderNo = generateOrderNo();
        order.setOrderNo(orderNo);
        order.setUserId(userId);
        order.setStatus(Order.Status.PENDING_PAYMENT.getCode());
        order.setTotalAmount(cartSummary.getTotalAmount());
        order.setPaymentAmount(cartSummary.getTotalAmount());
        order.setCreateTime(LocalDateTime.now());
        orderMapper.insert(order);

        /**
         * 注销的部分是插入 orderItem 表格，这部分代码不管我怎么改，都会报错 userid 空异常，无法正常插入
         * 找到问题，是 sql 插入有问题，缺少了 userid 字段
         * */
        List<OrderItem> orderItems = new ArrayList<>();
        for (CartVO cartItem : cartSummary.getCartItems()) {
            if (!productService.reduceStock(cartItem.getProductId(), cartItem.getQuantity())) {
                throw new BusinessException("商品库存不足：" + cartItem.getProductName());
            }
            OrderItem orderItem = new OrderItem();
            orderItem.setOrderId(order.getId());
            orderItem.setProductId(cartItem.getProductId());
            orderItem.setProductName(cartItem.getProductName());
            orderItem.setProductImage(cartItem.getProductImage());
            orderItem.setQuantity(cartItem.getQuantity());
            orderItem.setPrice(cartItem.getProductPrice());
            orderItem.setTotalAmount(cartItem.getTotalAmount());
            orderItem.setTotalPrice(cartItem.getTotalAmount());
            orderItem.setUserId(userId); //不能少插入用户ID
            orderItemMapper.insert(orderItem);
        }
        cartService.clearCheckedCart(userId);
        return orderNo;
    }
    
    @Override
    public PageResult<OrderVO.OrderListVO> getUserOrderPage(Long userId, Integer status, Integer pageNum, Integer pageSize) {
        if (pageNum == null || pageNum < 1) pageNum = 1;
        if (pageSize == null || pageSize < 1) pageSize = 10;
        int offset = (pageNum - 1) * pageSize;
    
        List<Order> orders = orderMapper.selectPage(offset, pageSize, userId, status, null);
        Long total = orderMapper.selectCount(userId, status, null);
    
        if (orders == null || orders.isEmpty()) {
            return PageResult.empty(pageNum, pageSize);
        }
    
        List<OrderVO.OrderListVO> orderVOs = orders.stream()
                .map(this::convertToListVO)
                .collect(Collectors.toList());
    
        return PageResult.of(total, pageNum, pageSize, orderVOs);
    }
    
    
    

    @Override
    @Transactional
    public String createDirectOrder(Long userId, OrderCreateDTO.DirectOrderDTO directOrderDTO) {
        List<OrderCreateDTO.DirectOrderDTO.OrderItem> items = directOrderDTO.getItems();
        if (items == null || items.isEmpty()) {
            throw new BusinessException("订单商品不能为空");
        }
        List<Product> products = new ArrayList<>();
        BigDecimal totalAmount = BigDecimal.ZERO;
        for (OrderCreateDTO.DirectOrderDTO.OrderItem item : items) {
            if (item.getProductId() == null || item.getQuantity() == null || item.getQuantity() <= 0) {
                throw new BusinessException("商品ID或数量非法");
            }
            Product product = productMapper.selectById(item.getProductId());
            if (product == null || product.getStatus() == null || product.getStatus() != 1) {
                throw new BusinessException("商品不存在或已下架：" + item.getProductId());
            }
            if (product.getStock() < item.getQuantity()) {
                throw new BusinessException("商品库存不足：" + product.getName());
            }
            products.add(product);
            totalAmount = totalAmount.add(product.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())));
        }
        Order order = new Order();
        String orderNo = generateOrderNo();
        order.setOrderNo(orderNo);
        order.setUserId(userId);
        order.setStatus(Order.Status.PENDING_PAYMENT.getCode());
        order.setTotalAmount(totalAmount);
        order.setPaymentAmount(totalAmount);
        order.setReceiverName(directOrderDTO.getReceiverName());
        order.setReceiverPhone(directOrderDTO.getReceiverPhone());
        order.setReceiverAddress(directOrderDTO.getReceiverAddress());
        order.setCreateTime(LocalDateTime.now());
        orderMapper.insert(order);
        List<OrderItem> orderItems = new ArrayList<>();
        for (int i = 0; i < items.size(); i++) {
            Product product = products.get(i);
            Integer quantity = items.get(i).getQuantity();
            OrderItem orderItem = new OrderItem(order.getId(), product, quantity);
            orderItem.setUserId(userId);
            orderItem.setTotalPrice(totalAmount);
            orderItemMapper.insert(orderItem);
            if (!productService.reduceStock(product.getId(), quantity)) {
                throw new BusinessException("库存扣减失败：" + product.getName());
            }
        }
        return orderNo;
    }

    @Override
    public OrderVO.OrderDetailVO getOrderDetail(Long userId, Long orderId) {
        Order order = orderMapper.selectByIdWithItems(orderId);
        if (order == null || !order.getUserId().equals(userId)) {
            throw new BusinessException("订单不存在");
        }
        List<OrderItem> orderItems = orderItemMapper.selectByOrderId(orderId);
        order.setOrderItems(orderItems);
        return convertToDetailVO(order);
    }

    // 管理端：订单详情
    @Override
    public OrderVO.OrderDetailVO getOrderDetailByAdmin(Long orderId) {
        Order order = orderMapper.selectByIdWithItems(orderId);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        List<OrderItem> orderItems = orderItemMapper.selectByOrderId(orderId);
        order.setOrderItems(orderItems);
        return convertToDetailVO(order);
    }

    // 管理端：删除订单
    @Override
    public void deleteOrderByAdmin(Long orderId) {
        orderMapper.deleteById(orderId);
        orderItemMapper.deleteByOrderId(orderId);
    }

    @Override
    public OrderVO.OrderDetailVO getOrderDetailByOrderNo(Long userId, String orderNo) {
        Order order = orderMapper.selectByOrderNoWithItems(orderNo);
        if (order == null || !order.getUserId().equals(userId)) {
            throw new BusinessException("订单不存在");
        }
        List<OrderItem> orderItems = orderItemMapper.selectByOrderId(order.getId());
        order.setOrderItems(orderItems);
        return convertToDetailVO(order);
    }

    @Override
    @Transactional
    public void confirmOrder(Long userId, Long orderId) {
        Order order = orderMapper.selectById(orderId);
        if (order == null || !order.getUserId().equals(userId)) {
            throw new BusinessException("订单不存在");
        }

        /**
         * 简化支付流程
         * */
//        if (!Order.Status.SHIPPED.getCode().equals(order.getStatus())) {
//            throw new BusinessException("订单状态不允许确认收货");
//        }
        orderMapper.updateStatus(orderId, Order.Status.COMPLETED.getCode());
    }

    @Override
    @Transactional
    public void deleteOrder(Long userId, Long orderId) {
        Order order = orderMapper.selectById(orderId);
        if (order == null || !order.getUserId().equals(userId)) {
            throw new BusinessException("订单不存在");
        }
        if (Order.Status.PENDING_PAYMENT.getCode().equals(order.getStatus())) {
            throw new BusinessException("待支付订单不允许删除");
        }
        orderMapper.deleteById(orderId);
        orderItemMapper.deleteByOrderId(orderId);
    }

    @Override
    @Transactional
    public void cancelOrder(Long userId, Long orderId) {
        Order order = orderMapper.selectByIdWithItems(orderId);
        if (order == null || !order.getUserId().equals(userId)) {
            throw new BusinessException("订单不存在");
        }
        if (!Order.Status.PENDING_PAYMENT.getCode().equals(order.getStatus())) {
            throw new BusinessException("订单状态不允许取消");
        }
        orderMapper.updateStatus(orderId, Order.Status.CANCELLED.getCode());
        if (order.getOrderItems() != null) {
            for (OrderItem item : order.getOrderItems()) {
                Product product = productMapper.selectById(item.getProductId());
                if (product != null) {
                    product.setStock(product.getStock() + item.getQuantity());
                    productMapper.updateById(product);
                }
            }
        }
    }

    @Override
    @Transactional
    public void cancelOrderByOrderNo(Long userId, String orderNo) {
        Order order = orderMapper.selectByOrderNoWithItems(orderNo);
        if (order == null || !order.getUserId().equals(userId)) {
            throw new BusinessException("订单不存在");
        }
        if (!Order.Status.PENDING_PAYMENT.getCode().equals(order.getStatus())) {
            throw new BusinessException("订单状态不允许取消");
        }
        orderMapper.updateStatusByOrderNo(orderNo, Order.Status.CANCELLED.getCode());
        if (order.getOrderItems() != null) {
            for (OrderItem item : order.getOrderItems()) {
                Product product = productMapper.selectById(item.getProductId());
                if (product != null) {
                    product.setStock(product.getStock() + item.getQuantity());
                    productMapper.updateById(product);
                }
            }
        }
    }

    @Override
    @Transactional
    public void payOrder(String orderNo) {
        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        if (!Order.Status.PENDING_PAYMENT.getCode().equals(order.getStatus())) {
            throw new BusinessException("订单状态不允许支付");
        }
        orderMapper.updateStatusByOrderNo(orderNo, Order.Status.PAID.getCode());
    }

    @Override
    @Transactional
    public void shipOrder(Long orderId) {
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        if (!Order.Status.PAID.getCode().equals(order.getStatus())) {
            throw new BusinessException("订单状态不允许发货");
        }
        orderMapper.updateStatus(orderId, Order.Status.SHIPPED.getCode());
    }

    @Override
    @Transactional
    public void updateOrderStatus(Long orderId, Integer status) {
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        orderMapper.updateStatus(orderId, status);
    }

    @Override
    public OrderStatisticsVO getOrderStatistics(Long userId) {
        OrderStatisticsVO statisticsVO = new OrderStatisticsVO();
        statisticsVO.setPendingPayment(orderMapper.countByUserIdAndStatus(userId, Order.Status.PENDING_PAYMENT.getCode()));
        statisticsVO.setPaid(orderMapper.countByUserIdAndStatus(userId, Order.Status.PAID.getCode()));
        statisticsVO.setShipped(orderMapper.countByUserIdAndStatus(userId, Order.Status.SHIPPED.getCode()));
        statisticsVO.setCompleted(orderMapper.countByUserIdAndStatus(userId, Order.Status.COMPLETED.getCode()));
        return statisticsVO;
    }

    private String generateOrderNo() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    private OrderVO.OrderListVO convertToListVO(Order order) {
        OrderVO.OrderListVO vo = new OrderVO.OrderListVO();
        BeanUtils.copyProperties(order, vo);
        Order.Status statusEnum = Order.Status.valueOf(order.getStatus());
        vo.setStatusDesc(statusEnum != null ? statusEnum.getDesc() : "未知状态");
        return vo;
    }

    private OrderVO.OrderDetailVO convertToDetailVO(Order order) {
        OrderVO.OrderDetailVO vo = new OrderVO.OrderDetailVO();
        BeanUtils.copyProperties(order, vo);
        Order.Status statusEnum = Order.Status.valueOf(order.getStatus());
        vo.setStatusDesc(statusEnum != null ? statusEnum.getDesc() : "未知状态");
        vo.setCanCancel(order.canCancel());
        vo.setCanPay(order.canPay());
        vo.setCanConfirm(order.canShip());
        if (order.getOrderItems() != null) {
            List<OrderVO.OrderItemVO> itemVOs = new ArrayList<>();
            for (OrderItem item : order.getOrderItems()) {
                OrderVO.OrderItemVO itemVO = new OrderVO.OrderItemVO();
                BeanUtils.copyProperties(item, itemVO);
                itemVOs.add(itemVO);
            }
            vo.setOrderItems(itemVOs);
        }
        return vo;
    }

    @Override
    public PageResult<OrderVO> getAllOrderPage(Integer status, String search, Integer pageNum, Integer pageSize) {
        if (pageNum == null || pageNum < 1) pageNum = 1;
        if (pageSize == null || pageSize < 1) pageSize = 10;

        int offset = (pageNum - 1) * pageSize;

        List<Order> orders = orderMapper.selectPage(offset, pageSize, null, status, search);
        Long total = orderMapper.selectCount(null, status, search);

        if (orders == null || orders.isEmpty()) {
            return PageResult.empty(pageNum, pageSize);
        }

        List<OrderVO> orderVOs = new ArrayList<>();
        for (Order order : orders) {
            OrderVO vo = new OrderVO();
            BeanUtils.copyProperties(order, vo);
            Order.Status statusEnum = Order.Status.valueOf(order.getStatus().toString());
            vo.setStatusDesc(statusEnum != null ? statusEnum.getDesc() : "未知状态");
            orderVOs.add(vo);
        }

        return PageResult.of(total, pageNum, pageSize, orderVOs);
    }
}
